/*
** cludp_echo.c
*/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/times.h>
#include <sys/timeb.h>
#include <unistd.h>

/* PORTA UTILIZADA */
#define PORT 3477  

/* NUMERO MAXIMO DE BYTES ENVIADOS/RECEBIDOS POR VEZ */
#define MAXDATASIZE 100

double difftimeb      (struct timeb* end, struct timeb* begin);

int main(int argc, char *argv[])
{
  int sockfd, numbytes;
  int sent_nl=0;
  int tschar=0, bgst_line=0;
  struct timeb ti, tf;
  double tt;
  char buf[MAXDATASIZE];
  socklen_t addr_len = sizeof(struct sockaddr);
  struct hostent *he;
  struct sockaddr_in their_addr; 

  if (argc != 2) {
    fprintf(stderr,"usage: client hostname\n");
    exit(1);
  }
  if ((he=gethostbyname(argv[1])) == NULL) { 
    perror("gethostbyname");
    exit(1);
  }
  if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
    perror("socket");
    exit(1);
  }

  their_addr.sin_family = AF_INET; 
  their_addr.sin_port   = htons(PORT);                      
  their_addr.sin_addr   = *((struct in_addr *)he->h_addr);
  bzero(&(their_addr.sin_zero), 8);                        
    
  //                             //
  /* INICIO DA CONTAGEM DO TEMPO */
  //                             //
  ftime(&ti);

  while (fgets (buf, MAXDATASIZE, stdin)) {

    // envio dos datagramas
    numbytes = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr));

    // contabilidade dos dados
    sent_nl++;
    tschar += numbytes;
    if (numbytes > bgst_line)
      bgst_line = numbytes;
  }

  // envio do datagrama de fechamento
  sendto(sockfd, buf, 0, 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr));

  //                            //
  /* FINAL DA CONTAGEM DO TEMPO */
  //                            //
  ftime(&tf);

  // CALCULO DO TEMPO TOTAL E IMPRESSAO DE DADOS
  tt = difftimeb(&tf,&ti);
  fprintf (stderr, "Tempo: %.3lfS\n", tt);
  fprintf (stderr, "Linhas enviadas: %d\nMaior linha: %d\nCaracteres enviados: %d\n\n", sent_nl, bgst_line, tschar);  

  return 0;
}

double difftimeb(struct timeb* end, struct timeb* begin) {
  double sec, milli;
  
  sec = (double)end->time - (double)begin->time;
  milli = (double)end->millitm - (double)begin->millitm;
  
  if (milli < 0) {
    sec--;
    milli += 1000.0;
  }
  
  sec += milli / 1000.0;
  
  return sec;
}
